package com.im.gateway.tcp;

import com.alibaba.fastjson.JSONObject;
import com.google.protobuf.InvalidProtocolBufferException;
import com.im.common.*;
import com.im.gateway.tcp.dispatcher.DispatcherInstance;
import com.im.gateway.tcp.dispatcher.DispatcherInstanceManager;
import com.im.gateway.tcp.service.AuthService;
import com.im.gateway.tcp.util.SpringContextUtil;
import com.im.protocol.*;
import io.netty.channel.socket.SocketChannel;

/**
 * 用户认证处理组件
 * @Created leijun
 * @Date 2021/9/16 7:15 上午
 */
public class RequestHandler {

    private RequestHandler() {}

    static class Singleton {
        private static RequestHandler instance = new RequestHandler();
    }
    public static RequestHandler getInstance() {
        return Singleton.instance;
    }
    /**
     * 请求认证
     * @param socketChannel
     * @param request
     * @return
     */
    public void authenticate(SocketChannel socketChannel, Request request) throws InvalidProtocolBufferException {
        AuthenticateRequestProto.AuthenticateRequest authenticateRequest =
                AuthenticateRequestProto.AuthenticateRequest.parseFrom(request.getBody());
        AuthService authService = SpringContextUtil.getBean(AuthService.class);
        AuthenticateResponseProto.AuthenticateResponse.Builder respBuilder =
                AuthenticateResponseProto.AuthenticateResponse.newBuilder();
        try {
            Result result = authService.auth(authenticateRequest.getToken());
            if (result.getCode() == ResponseStatus.SUCCESS.getCode()) {
                // 发送认证请求之后将客户端保存起来
                SessionManager sessionManager = SessionManager.getInstance();
                sessionManager.addSession(authenticateRequest.getUid(), socketChannel);

                String socketChannelId = socketChannel.remoteAddress().getHostName() + ":" + socketChannel.remoteAddress().getPort();
                String sessionKey = "session_"+authenticateRequest.getUid();
                SessionInfo sessionInfo = new SessionInfo();
                sessionInfo.setToken(authenticateRequest.getToken());
                sessionInfo.setTimestamp(authenticateRequest.getTimestamp());
                sessionInfo.setAuthTimestamp(System.currentTimeMillis());
                sessionInfo.setChannelId(socketChannelId);
                JedisManager jedisManager = JedisManager.getInstance();
                jedisManager.getJedis().set(sessionKey, JSONObject.toJSONString(sessionInfo));

                respBuilder.setErrorCode(0);
                respBuilder.setErrorMessage("认证成功");
                respBuilder.setStatus(ResponseCode.OK);
                respBuilder.setUid(authenticateRequest.getUid());
                respBuilder.setToken(authenticateRequest.getToken());
                respBuilder.setTimestamp(authenticateRequest.getTimestamp());
            } else {
                respBuilder.setErrorCode(0);
                respBuilder.setErrorMessage("认证失败");
                respBuilder.setStatus(ResponseCode.ERROR);
            }
        } catch (Exception e) {
            respBuilder.setErrorCode(-1);
            respBuilder.setErrorMessage("认证系统响应失败");
        }
        AuthenticateResponseProto.AuthenticateResponse authenticateResponse = respBuilder.build();
        Response response = new Response(request.getAppSdkVersion(), request.getRequestType(),
                request.getSequence(), authenticateResponse.toByteArray());
        socketChannel.writeAndFlush(response.getBuf());
    }
    /**
     * 发送单聊消息
     * @param messageRequest
     */
    public void sendMessage(MessageRequestProto.MessageRequest messageRequest) {
        DispatcherInstanceManager dispatcherInstanceManager = DispatcherInstanceManager.getInstance();
        DispatcherInstance dispatcherInstance = dispatcherInstanceManager.chooseDispatcherInstance();
        dispatcherInstance.sendMessage(messageRequest);
    }

    /**
     * 发送群聊消息
     * @param messageRequest
     */
    public void sendGroupMessage(GroupMessageRequestProto.GroupMessageRequest messageRequest) {
        DispatcherInstanceManager dispatcherInstanceManager = DispatcherInstanceManager.getInstance();
        DispatcherInstance dispatcherInstance = dispatcherInstanceManager.chooseDispatcherInstance();
        dispatcherInstance.sendGroupMessage(messageRequest);
    }

    /**
     * 处理消息推送响应
     * @param pushMessageResponse
     */
    public void pushMessageResponse(PushMessageResponseProto.PushMessageResponse pushMessageResponse) {
        DispatcherInstanceManager dispatcherInstanceManager = DispatcherInstanceManager.getInstance();
        DispatcherInstance dispatcherInstance = dispatcherInstanceManager.chooseDispatcherInstance();
        dispatcherInstance.pushMessageResponse(pushMessageResponse);
    }

}
